/******************************************************************************************************************
 * File:WindowSensor.java
 * Course: 17655
 * Project: Assignment A3
 * Copyright: Copyright (c) 2009 Carnegie Mellon University
 * Versions:
 *	1.0 March 2009 - Initial rewrite of original assignment 3 (ajl).
 *
 * Description:
 *
 * This class simulates a Window sensor. It polls the event manager for events corresponding to changes in state
 * of the humidifier or dehumidifier and reacts to them by trending the relative Window up or down. The current
 * relative Window is posted to the event manager.
 *
 * Parameters: IP address of the event manager (on command line). If blank, it is assumed that the event manager is
 * on the local machine.
 *
 * Internal Methods:
 *	float GetRandomNumber()
 *	boolean CoinToss()
 *   void PostWindow(EventManagerInterface ei, float Window )
 *
 ******************************************************************************************************************/
import InstrumentationPackage.*;
import EventPackage.*;

import java.util.*;

class WindowSensor { 
	static MessageWindow mw = null;
	static boolean controlFlag = false;

	public static void main(String args[])
	{
		String EvtMgrIP;					// Event Manager IP address
		Event Evt = null;					// Event object
		EventQueue eq = null;				// Message Queue
		int EvtId = 0;						// User specified event ID
		EventManagerInterface em = null;	// Interface object to the event manager
		boolean WindowState = false;	// Window state: false == not broken, true == broken
		int	Delay = 1000;					// The loop delay (2.5 seconds)
		boolean Done = false;				// Loop termination flag
		
	


		
		/////////////////////////////////////////////////////////////////////////////////
		// Get the IP address of the event manager
		/////////////////////////////////////////////////////////////////////////////////

 		if ( args.length == 0 )
 		{
			// event manager is on the local system

			System.out.println("\n\nAttempting to register on the local machine..." );

			try
			{
				// Here we create an event manager interface object. This assumes
				// that the event manager is on the local machine

				em = new EventManagerInterface();
			}

			catch (Exception e)
			{
				System.out.println("Error instantiating event manager interface: " + e);

			} // catch

		}else if (args.length > 1) {
			// case where ip and binding name and passed along as command line
			// args
			long beatTime = 5000;

			// Send heart beat in default time interview

			try {
				// Here we create an event manager interface object. This
				// assumes
				// that the event manager is NOT on the local machine

				em = new EventManagerInterface(args[0], args[1]);
				if (args.length > 2) {
					// Launching heartbeat
					try {
						// Here we create an heart beat event manager interface
						// object. This
						// assumes
						// that the event manager is NOT on the local machine
						EventManagerInterface hbManager = new EventManagerInterface(
								args[2], args[3]);
						EventPackage.Event evt = new Event((int) 12);
						evt.SetSenderId(em.GetMyId());
						HeartBeat.startThread(hbManager, evt, beatTime);

						if (args.length == 6) {
							String name = args[4];
							String description = args[5];
							EventPackage.Event evt2 = new Event((int) 11, name
									+ '%' + description);
							evt2.SetSenderId(em.GetMyId());
							HeartBeat.startThread(hbManager, evt2, 30000);

						}
					} catch (Exception exp) {
						System.out.println("Failed starting Heartbeat");
					}
				}

			} catch (Exception e) {
				System.out
						.println("Error instantiating event manager interface: "
								+ e);

			} // catch
		} else {

			// event manager is not on the local system

			EvtMgrIP = args[0];

			System.out.println("\n\nAttempting to register on the machine:: "
					+ EvtMgrIP);

			try {
				// Here we create an event manager interface object. This
				// assumes
				// that the event manager is NOT on the local machine

				em = new EventManagerInterface(EvtMgrIP);
			}

			catch (Exception e) {
				System.out
						.println("Error instantiating event manager interface: "
								+ e);

			} // catch

		} // if
 		
 		
 		if (em != null)
		{

			// We create a message window. Note that we place this panel about 1/2 across 
			// and 2/3s down the screen
			
			float WinPosX = 0.7f; 	//This is the X position of the message window in terms 
									//of a percentage of the screen height
			float WinPosY = 0.80f;	//This is the Y position of the message window in terms 
								 	//of a percentage of the screen height 
			
			mw = new MessageWindow("Window Sensor", WinPosX, WinPosY);

			mw.WriteMessage("Registered with the event manager." );

	    	try
	    	{
				mw.WriteMessage("   Participant id: " + em.GetMyId() );
				mw.WriteMessage("   Registration Time: " + em.GetRegistrationTime() );

			} // try

	    	catch (Exception e)
			{
				mw.WriteMessage("Error:: " + e);

			} // catch
		

	    	mw.WriteMessage("Window Sensors Activated!");
		}
		
			while ( !Done )
			{
				// Post the current relative Window

				// Get the message queue

				try
				{
					eq = em.GetEventQueue();

				} // try

				catch( Exception e )
				{
					System.out.println("Error getting event queue::" + e );

				} // catch

				// If there are messages in the queue, we read through them.
				// We are looking for EventIDs = -4, this means the the humidify or
				// dehumidifier has been turned on/off. Note that we get all the messages
				// from the queue at once... there is a 2.5 second delay between samples,..
				// so the assumption is that there should only be a message at most.
				// If there are more, it is the last message that will effect the
				// output of the Window as it would in reality.

				int qlen = eq.GetSize();
				
				for ( int i = 0; i < qlen; i++ )
				{
					Evt = eq.GetEvent();

					if ( Evt.GetEventId() == -6 )
					{

						if (Evt.GetMessage().equalsIgnoreCase("WB")) // humidifier off
						{
							WindowState = true;
							controlFlag = true;
							

						} // if
						if (Evt.GetMessage().equalsIgnoreCase("WF")) // humidifier off
						{
							WindowState = false;
							controlFlag = false;
							

						} // if

						
					} // if

					// If the event ID == 99 then this is a signal that the simulation
					// is to end. At this point, the loop termination flag is set to
					// true and this process unregisters from the event manager.

					if ( Evt.GetEventId() == 99 )
					{
						Done = true;

						try
						{
							em.UnRegister();

				    	} // try

				    	catch (Exception e)
				    	{
							System.out.println("Error unregistering: " + e);

				    	} // catch

				    	System.out.println("\n\nSimulation Stopped. \n");

					} // if

				} // for

				// Now we trend the relative Window according to the status of the
				// humidifier/dehumidifier controller.

			if(controlFlag)	
			{
				if (WindowState)
				{
					PostWindowEvent( em, true );
					//controlFlag = false;

				} // if humidifier is on

			}

				

				// Here we wait for a 2.5 seconds before we start the next sample

				try
				{
					Thread.sleep( Delay );

				} // try

				catch( Exception e )
				{
					System.out.println("Sleep error:: " + e );

				} // catch

			} // while


	} // main


	/***************************************************************************
	* CONCRETE METHOD:: PostWindow
	* Purpose: This method posts the specified relative Window value to the
	* specified event manager. This method assumes an event ID of 2.
	*
	* Arguments: EventManagerInterface ei - this is the eventmanger interface
	*			 where the event will be posted.
	*
	*			 float Window - this is the Window value.
	*
	* Returns: none
	*
	* Exceptions: None
	*
	***************************************************************************/

	static private void PostWindowEvent(EventManagerInterface ei, boolean broken )
	{
		// Here we create the event.
		
		Event evt = null;
		
		if(broken){
			evt = new Event( (int) 6, "WB" );
			mw.WriteMessage("Window Broken!");
		}


		// Here we send the event to the event manager.

		try
		{
			ei.SendEvent( evt );
			//mw.WriteMessage( "Sent Window Event" );

		} // try

		catch (Exception e)
		{
			System.out.println( "Error Posting Window status:: " + e );

		} // catch
		
		

	} // PostWindow

} // Window Sensor 
